
package com.sbtr.business.calibration.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sbtr.business.calibration.entity.*;
import com.sbtr.business.calibration.mapper.CalibrationMapper;
import com.sbtr.business.calibration.service.ICalibrationService;
import com.sbtr.common.PageDto;
import com.sbtr.constant.CalibrationConstant;
import com.sbtr.constant.ColumnConstant;
import com.sbtr.open.calibration.dto.*;
import com.sbtr.util.BeanCopyUtils;
import com.sbtr.util.PageDtoUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;


/**
 * <p>
 * 标定集 服务实现类
 * </p>
 */
@Transactional
@Service
public class CalibrationServiceImpl extends ServiceImpl<CalibrationMapper, Calibration>
        implements ICalibrationService {

    private static final Logger logger = LoggerFactory.getLogger(CalibrationServiceImpl.class);

//	@Autowired
//	private RoleServiceImpl roleService;

    @Autowired
    private CalibrationServiceTxtImpl calibrationTxtService;

    @Autowired
    private CalibrationImgServiceImpl calibrationImgService;

    @Autowired
    private CalibrationVoiceServiceImpl calibrationVoiceService;

    @Autowired
    private CalibrationDetailsServiceImpl calibrationDetailsService;

    @Autowired
    @Lazy
    private CalibrationServiceImpl calibrationServiceImpl;

    @Autowired
    @Lazy
    private CalibrationDetailsServiceImpl calibrationDetailsServiceImpl;


    //    @Value("${minio.bucketName}")
    private String bucketName = "test";

    private static final String REGEX = "；"; //分隔符，中文分号

    @Value("${oss.config.uploadPath}")
    private String uploadPath;


    @Override
    public CalibrationDto update(CalibrationDto dto) {
        Calibration calibration = BeanCopyUtils.copyProperties(dto, Calibration.class);
        calibration.setId(dto.getId());
        updateById(calibration);
        return dto;

    }


    /**
     * 分页查询我发布的任务列表
     * 1.查询当前有效的，
     * 2.支持 "标注任务名称"、"创建者"、"标注状态"、“优先级”、“任务类型”、“标注素材数量”、“标签数量”等属性进行查询
     *
     * @param pro
     * @return
     */
    @Override
    public PageDto<CalibrationDto> search(CalibrationSearchDto pro) {
        IPage<Calibration> page = new Page<>();
        page.setSize(pro.getPageSize());
        page.setCurrent(pro.getPage());
        QueryWrapper<Calibration> wrapper = new QueryWrapper<>();
        wrapper.eq(ColumnConstant.IS_AVAILABLE, 1);
        if (null != pro.getId()) {
            wrapper.like(ColumnConstant.ID, pro.getId());
        }
        if (StringUtils.isNotEmpty(pro.getCalibrationName())) {
            wrapper.like(ColumnConstant.CALIBRATION_NAME, pro.getCalibrationName());
        }

        if (StringUtils.isNotEmpty(pro.getCreater())) {
            wrapper.eq(ColumnConstant.CREATER, pro.getCreater());
        }


        if (null != pro.getStatus() && !pro.getStatus().isEmpty()) {
            wrapper.in(ColumnConstant.STATUS, pro.getStatus());
        }

        if (null != pro.getPriority() && !pro.getPriority().isEmpty()) {
            wrapper.in(ColumnConstant.TASK_PRIORITY, pro.getPriority());
        }

        if (null != pro.getTaskType() && !pro.getTaskType().isEmpty()) {
            wrapper.in(ColumnConstant.TASK_TYPE, pro.getTaskType());
        }

        if (null != pro.getTotalCount()) {
            wrapper.eq(ColumnConstant.TOTAL_COUNT, pro.getTotalCount());
        }

        if (null != pro.getClassifyCount()) {
            wrapper.eq(ColumnConstant.CLASSIFY_COUNT, pro.getClassifyCount());
        }

//		标注完成率（表中无该字段）
//		if (null != pro.getId()) {
//			wrapper.eq(ColumnConstant.FILE_SIZE, pro.getFileSize());
//		}

        if (null != pro.getCreateTime()) {
            Date startTime = pro.getCreateTime(); //取时间
            Calendar calendar = new GregorianCalendar();
            calendar.setTime(startTime);
            calendar.add(calendar.DATE, 1); //把日期往后增加一天,整数  往后推,负数往前移动
            startTime = calendar.getTime(); //这个时间就是日期往后推一天的结果
            wrapper.between(ColumnConstant.CREATE_TIME, pro.getCreateTime(), startTime);
        }

        if (null != pro.getFinishedTime()) {
            Date startTime = pro.getFinishedTime(); //取时间
            Calendar calendar = new GregorianCalendar();
            calendar.setTime(startTime);
            calendar.add(calendar.DATE, 1); //把日期往后增加一天,整数  往后推,负数往前移动
            startTime = calendar.getTime(); //这个时间就是日期往后推一天的结果
            wrapper.between(ColumnConstant.FINISHED_TIME, pro.getFinishedTime(), startTime);
        }

        if (null != pro.getUpdateTime()) {
            Date startTime = pro.getUpdateTime(); //取时间
            Calendar calendar = new GregorianCalendar();
            calendar.setTime(startTime);
            calendar.add(calendar.DATE, 1); //把日期往后增加一天,整数  往后推,负数往前移动
            startTime = calendar.getTime(); //这个时间就是日期往后推一天的结果
            wrapper.between(ColumnConstant.UPDATE_TIME, pro.getUpdateTime(), startTime);
        }

        wrapper.orderByDesc("id");
        page = page(page, wrapper);
        PageDto<CalibrationDto> pageDto = PageDtoUtils.getPageDtoByIPage(page, CalibrationDto.class);
        return pageDto;
    }


//	@Override
//	@PostMapping(value = "/{id}/saveObjectDetectionLabel")
//	public CalibrationObjectDetectionDto saveObjectDetectionLabel(Long calibrationId, CalibrationObjectDetectionDto dto) {
//
//		if(null != calibrationId && calibrationId !=0) {
//			dto.setCalibrationId(calibrationId);
//
//			//需要同时写json文件，添加一条记录
//
//			return calibrationObjectDetectionApi.save(dto);
//		}
//		return null;
//	}

    @Override
    public List<CalibrationTxtDto> saveTxtDetails(Long calibrationDetailsId, List<CalibrationTxtDto> dtos) {


        List<CalibrationTxt> details = BeanCopyUtils.copyProperties(dtos, CalibrationTxt.class);
        boolean tag = true;
        for (CalibrationTxtDto detail : dtos) {
            detail.setCalibrationId(detail.getCalibrationId());

            if (StringUtils.isNotBlank(detail.getClassifyName())) { //是否跳过
                detail.setClassifyId(detail.getClassifyId());
                detail.setClassifyName(detail.getClassifyName());
                detail.setCompleted("1");
            } else {
                detail.setCompleted("0");
            }
            tag = tag && calibrationTxtService.update(detail);
        }


        CalibrationDetailsDto calibrationDetails = calibrationDetailsServiceImpl.findById(calibrationDetailsId);

        if (tag) {
            // 更新总的标定集的数据统计
            this.updateCalibrationSetTxtCount(calibrationDetails.getCalibrationId());
            //更新个人标定的数据集
            CalibrationDto calibration = findById(calibrationDetails.getCalibrationId());
            calibrationDetailsServiceImpl.updateCalibrationDetailsTxtCount(calibration);
            //更新每日标注统计
            calibrationTxtService.updateCalibrationTxtRecordDaily(calibrationDetails);
        }

        return BeanCopyUtils.copyProperties(details, CalibrationTxtDto.class);

    }


    // 更新文本类型的标定统计数据
    @Override
    public boolean updateCalibrationSetTxtCount(Long calibrationIds) {
        QueryWrapper<Calibration> wrapper = new QueryWrapper<>();
        wrapper.in("id", calibrationIds);
        List<Calibration> list = list(wrapper);
        if (list != null && !list.isEmpty()) {


            //统计每个的任务所有人的数据
            List<CalibrationCountByFinisherDto> countTxtDto = calibrationTxtService.countTaskByCalibrationIds(calibrationIds);

            int TotalCount = 0;
            int Completed = 0;
            for (CalibrationCountByFinisherDto dto : countTxtDto) {
                TotalCount += dto.getCompleted() + dto.getUncompleted();
                Completed += dto.getCompleted();
            }

            //更新总览的数据
            CalibrationDto calibrationDto = calibrationServiceImpl.findById(calibrationIds);

            calibrationDto.setTotalCount(TotalCount);
            calibrationDto.setCompleted(Completed);
            if (TotalCount == Completed) {
                calibrationDto.setStatus(CalibrationConstant.TASK_STATUS_COMPLETED);
            } else {
                calibrationDto.setStatus(CalibrationConstant.TASK_STATUS_CALIBRATING);
            }

            calibrationDto = calibrationServiceImpl.update(calibrationDto);
            if (calibrationDto != null) {
                return true;
            } else {
                return false;
            }
        }
        return true;
    }


    public List<CalibrationCountDto> txtDetailCompleteCount(List<Long> calibrationIds) {
        return baseMapper.txtDetailCompleteCount(calibrationIds);
    }


    private List<CalibrationCountDto> getCountByNoDetailTxt(List<Long> calibrationIds) {

        return baseMapper.txtDetailNOCompleteCount(calibrationIds);
//		List<CalibrationCountDto> resultList = new ArrayList<>();
//		for (Long id : calibrationSetIds) {
//			CalibrationCountDto dto = this.getTxtCompleteCountBymetaData(id);
//			if (dto != null) {
//				resultList.add(dto);
//			}
//		}
//		return resultList;
    }

    /**
     * 进行批量关联性逻辑删除，仅仅修改isAvailable属性参数为0
     *
     * @param idList
     * @return
     */
    @Override
    public Boolean batchDeleteById(List<Long> idList) {
        for (Long id : idList) {
            baseMapper.updateIsAvailableById(id);
        }
        // 并修改详发布任务详细信息列表为无效
        calibrationDetailsService.updateIsAvailable(idList);
        return true;
    }

    @Override
    public CalibrationDto save(CalibrationDto dto) {
        Calibration data = BeanCopyUtils.copyProperties(dto, Calibration.class);
        if (dto.getId() == null) {
            save(data);
            dto.setId(data.getId());
        } else {
            return BeanCopyUtils.copyProperties(data, CalibrationDto.class);
        }
        return dto;
    }

    @Override
    public CalibrationDto findById(Long id) {
        return BeanCopyUtils.copyProperties(getById(id), CalibrationDto.class);
    }

    public Integer getCount(String taskType, Long calibrationId, String finisher, String completed) {
        if (taskType.equals(CalibrationConstant.PROJECT_TYPE_IMG_CLASSIFY)) {
            QueryWrapper<CalibrationImg> wrapper = new QueryWrapper<>();
            wrapper.eq("calibration_id", calibrationId);
            if (StringUtils.isNotEmpty(finisher)) {
                wrapper.eq("finisher", finisher);
            }
            if (StringUtils.isNotEmpty(completed)) {
                wrapper.eq("completed", completed);
            }
            return calibrationImgService.count(wrapper);
        } else {
            QueryWrapper<CalibrationVoice> wrapper = new QueryWrapper<>();
            wrapper.eq("calibration_id", calibrationId);
            if (StringUtils.isNotEmpty(finisher)) {
                wrapper.eq("finisher", finisher);
            }
            if (StringUtils.isNotEmpty(completed)) {
                wrapper.eq("completed", completed);
            }
            return calibrationVoiceService.count(wrapper);
        }


    }

    @Override
    public List<CalibrationDetailsDto> divisionImgDetectTask(Long calibrationId, String finisher) {
        Calibration calibration = getById(calibrationId);
        String taskType = calibration.getTaskType();
        List<CalibrationDetailsDto> CalibrationDetailsDtoList = calibrationDetailsService.searchDetailsCalibrationId(calibrationId);
        List<CalibrationDetailsDto> newcalibrationDetails = new ArrayList<>();
        if (CalibrationDetailsDtoList.isEmpty()) {//完全没有子任务则新建
            //Calibration calibration = getById(calibrationId);
            String finishertmp[] = calibration.getFinisher().split(",");
            int userlength = finishertmp.length;
            for (String username : finishertmp) {
                CalibrationDetailsDto calibrationDetail = BeanCopyUtils.copyProperties(calibration, CalibrationDetailsDto.class);
                calibrationDetail.setId(null);//新增
                calibrationDetail.setCalibrationId(calibration.getId());
                calibrationDetail.setCreateTime(new Date());
                calibrationDetail.setFinisher(username);
                calibrationDetail.setStatus(CalibrationConstant.TASK_STATUS_CALIBRATING);
                calibrationDetail.setCompleted(0);
                newcalibrationDetails.add(calibrationDetail);
            }
            List<CalibrationDetails> result = BeanCopyUtils.copyProperties(newcalibrationDetails, CalibrationDetails.class);
            boolean success = calibrationDetailsService.saveBatch(result);
            if (success) {
                return BeanCopyUtils.copyProperties(result, CalibrationDetailsDto.class);
            } else {
                return null;
            }

        } else {//已有子任务则，再新建子任务
            //throw new RuntimeException("该任务已被分配，不允许在分配");
            if (StringUtils.isEmpty(finisher)) {
                finisher = calibration.getFinisher();
            }
            //再次分配给新的任务人
            String finishers[] = finisher.split(",");//“新的”任务处理人
            for (String username : finishers) {
                //查询是否已经有子任务
                CalibrationDetailsDto calibrationDetail = calibrationDetailsService.searchDetailsFinisher(calibrationId, username);
                if (calibrationDetail == null) {//新增
                    calibrationDetail = BeanCopyUtils.copyProperties(calibration, CalibrationDetailsDto.class);
                    calibrationDetail.setId(null);//新增
                    calibrationDetail.setCalibrationId(calibration.getId());
                    calibrationDetail.setCreateTime(new Date());
                    calibrationDetail.setFinisher(username);
                    calibrationDetail.setStatus(CalibrationConstant.TASK_STATUS_CALIBRATING);
                    calibrationDetail.setCompleted(0);
                    calibrationDetail.setTotalCount(0);//新增的为0   不然会从主任务复制到total_count
                }
                newcalibrationDetails.add(calibrationDetail);
            }
            List<CalibrationDetails> result = BeanCopyUtils.copyProperties(newcalibrationDetails, CalibrationDetails.class);
            boolean success = calibrationDetailsService.saveOrUpdateBatch(result);
            if (success) {
                return BeanCopyUtils.copyProperties(result, CalibrationDetailsDto.class);
            } else {
                return null;
            }
        }
    }

    @Override
    public boolean updateCalibrationAndCalibrationDetails(CalibrationDto calibrationDto, String finisher) {
        Long calibrationId = calibrationDto.getId();
        String taskType = calibrationDto.getTaskType();
        List<CalibrationDetailsDto> CalibrationDetailsDtoList = calibrationDetailsService.searchDetailsCalibrationId(calibrationId);
        List<String> oldFinishers = new ArrayList<>(Arrays.asList(calibrationDto.getFinisher().split(",")));

        //更新接收任务的数据
        if (CalibrationDetailsDtoList.size() == 0) {//第一次导入数据
            List<CalibrationDetailsDto> newcalibrationDetails = new ArrayList<>(); //以分隔符分割的素材
            for (int i = 0; i < oldFinishers.size(); i++) {
//				QueryWrapper<CalibrationImg> wrapper2 = new QueryWrapper<>();
//				wrapper2.eq("calibration_id", calibrationId);
//				wrapper2.eq("finisher",oldFinishers.get(i));
//				Integer totalCount2 = calibrationImgService.count(wrapper2);
//				wrapper2.eq("completed", "1");
//				Integer completeCount2 = calibrationImgService.count(wrapper2);
                Integer totalCount2 = getCount(taskType, calibrationId, oldFinishers.get(i), null);
                Integer completeCount2 = getCount(taskType, calibrationId, oldFinishers.get(i), "1");
                CalibrationDetailsDto calibrationDetail = new CalibrationDetailsDto();
                calibrationDetail.setCalibrationId(calibrationDto.getId());
                calibrationDetail.setCalibrationName(calibrationDto.getCalibrationName());
                calibrationDetail.setCalibrationDesc(calibrationDto.getCalibrationDesc());
                calibrationDetail.setClassifyCount(calibrationDto.getClassifyCount());
                calibrationDetail.setTaskType(calibrationDto.getTaskType());
                calibrationDetail.setCreater(calibrationDto.getCreater());
                calibrationDetail.setCreateTime(new Date());
                calibrationDetail.setFinishedTime(calibrationDto.getFinishedTime());
                calibrationDetail.setFinisher(oldFinishers.get(i));
                calibrationDetail.setStatus(CalibrationConstant.TASK_STATUS_CALIBRATING);
                calibrationDetail.setPriority(calibrationDto.getPriority());
                calibrationDetail.setCompleted(completeCount2);
                calibrationDetail.setTotalCount(totalCount2);
                newcalibrationDetails.add(calibrationDetail);
            }
            calibrationDetailsServiceImpl.batchSave(newcalibrationDetails);
        } else {//不是第一次导入数据
            List<String> newFinishers = Arrays.asList(finisher.split(","));
            List<CalibrationDetailsDto> calibrationDetails = new ArrayList<>();
            for (int i = 0; i < newFinishers.size(); i++) {
//				QueryWrapper<CalibrationImg> wrapper2 = new QueryWrapper<>();
//				wrapper2.eq("calibration_id", calibrationId);
//				wrapper2.eq("finisher",newFinishers.get(i));
//				Integer totalCount2 = calibrationImgService.count(wrapper2);
//				wrapper2.eq("completed", "1");
//				Integer completeCount2 = calibrationImgService.count(wrapper2);
                Integer totalCount2 = getCount(taskType, calibrationId, newFinishers.get(i), null);
                Integer completeCount2 = getCount(taskType, calibrationId, newFinishers.get(i), "1");

                if (!oldFinishers.contains(newFinishers.get(i))) {//是新人

                    CalibrationDetailsDto calibrationDetail = new CalibrationDetailsDto();
                    calibrationDetail.setCalibrationId(calibrationDto.getId());
                    calibrationDetail.setCalibrationName(calibrationDto.getCalibrationName());
                    calibrationDetail.setCalibrationDesc(calibrationDto.getCalibrationDesc());
                    calibrationDetail.setClassifyCount(calibrationDto.getClassifyCount());
                    calibrationDetail.setTaskType(calibrationDto.getTaskType());
                    calibrationDetail.setCreater(calibrationDto.getCreater());
                    calibrationDetail.setCreateTime(new Date());
                    calibrationDetail.setFinishedTime(calibrationDto.getFinishedTime());
                    calibrationDetail.setFinisher(newFinishers.get(i));
                    calibrationDetail.setStatus(CalibrationConstant.TASK_STATUS_CALIBRATING);
                    calibrationDetail.setPriority(calibrationDto.getPriority());
                    calibrationDetail.setCompleted(completeCount2);
                    calibrationDetail.setTotalCount(totalCount2);
                    calibrationDetails.add(calibrationDetail);
                } else {//不是新人
                    CalibrationDetailsDto calibrationDetail = calibrationDetailsService.searchDetailsFinisher(calibrationId, newFinishers.get(i));
                    calibrationDetail.setCompleted(completeCount2);
                    calibrationDetail.setTotalCount(totalCount2);
                    if (completeCount2.equals(totalCount2)) {
                        calibrationDetail.setStatus(CalibrationConstant.TASK_STATUS_COMPLETED);
                    } else {
                        calibrationDetail.setStatus(CalibrationConstant.TASK_STATUS_CALIBRATING);
                    }
                    calibrationDetailsServiceImpl.update(calibrationDetail);
                }

            }
            calibrationDetailsServiceImpl.batchSave(calibrationDetails);
        }

        //更新发布任务的数据
//		QueryWrapper<CalibrationImg> wrapper1 = new QueryWrapper<>();
//		wrapper1.eq("calibration_id", calibrationId);
//		Integer totalCount = calibrationImgService.count(wrapper1);
//		wrapper1.eq("completed", "1");
//		Integer completeCount = calibrationImgService.count(wrapper1);
        Integer totalCount = getCount(taskType, calibrationId, null, null);
        Integer completeCount = getCount(taskType, calibrationId, null, "1");


        Calibration calibration = getById(calibrationId);
        calibration.setTotalCount(totalCount);
        calibration.setCompleted(completeCount);
        if (CalibrationDetailsDtoList.size() != 0) {//不是第一次导入数据
            List<String> newFinishers = new ArrayList<>(Arrays.asList(finisher.split(",")));
            oldFinishers.addAll(newFinishers);
            Set<String> finisherSet = new HashSet<>(oldFinishers);
            String resultFinishers = StringUtils.join(finisherSet.toArray(), ",");
            calibration.setFinisher(resultFinishers);
        }

        if (completeCount.equals(totalCount)) {
            calibration.setStatus(CalibrationConstant.TASK_STATUS_COMPLETED);
        } else {
            calibration.setStatus(CalibrationConstant.TASK_STATUS_CALIBRATING);
        }
        updateById(calibration);

        return true;
    }

}